﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BoneImp {
	class ColorTimeline : BaseTimeline {
		//int framesLength;
		//float[] frames; /* time, r, g, b, a, ... */
		int slotIndex;

		const int COLOR_LAST_FRAME_TIME = -5;
		const int COLOR_FRAME_R = 1;
		const int COLOR_FRAME_G = 2;
		const int COLOR_FRAME_B = 3;
		const int COLOR_FRAME_A = 4;

		public ColorTimeline(int frameCount) : base(frameCount, 5) {
		}

		public override void apply(SkeletonBase skeleton, float time, float alpha) {
			if (time < this.frames[0]) return; /* Time is before first frame. */

			Slot slot = skeleton.slots[this.slotIndex];

			if (time >= this.frames[this.framesLength - 5]) { /* Time is after last frame. */
				int i = this.framesLength - 1;
				slot.r = this.frames[i - 3];
				slot.g = this.frames[i - 2];
				slot.b = this.frames[i - 1];
				slot.a = this.frames[i];
				return;
			}

			/* Interpolate between the last frame and the current frame. */
			int frameIndex = binarySearch(this.frames, this.framesLength, time, 5);
			float lastFrameR = this.frames[frameIndex - 4];
			float lastFrameG = this.frames[frameIndex - 3];
			float lastFrameB = this.frames[frameIndex - 2];
			float lastFrameA = this.frames[frameIndex - 1];
			float frameTime = this.frames[frameIndex];
			float percent = 1 - (time - frameTime) / (this.frames[frameIndex + COLOR_LAST_FRAME_TIME] - frameTime);
			percent = this.getCurvePercent(frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));

			float r = lastFrameR + (this.frames[frameIndex + COLOR_FRAME_R] - lastFrameR) * percent;
			float g = lastFrameG + (this.frames[frameIndex + COLOR_FRAME_G] - lastFrameG) * percent;
			float b = lastFrameB + (this.frames[frameIndex + COLOR_FRAME_B] - lastFrameB) * percent;
			float a = lastFrameA + (this.frames[frameIndex + COLOR_FRAME_A] - lastFrameA) * percent;
			if (alpha < 1) {
				slot.r += (r - slot.r) * alpha;
				slot.g += (g - slot.g) * alpha;
				slot.b += (b - slot.b) * alpha;
				slot.a += (a - slot.a) * alpha;
			} else {
				slot.r = r;
				slot.g = g;
				slot.b = b;
				slot.a = a;
			}
		}

		void setFrame(int frameIndex, float time, float r, float g, float b, float a) {
			frameIndex *= 5;
			this.frames[frameIndex] = time;
			this.frames[frameIndex + 1] = r;
			this.frames[frameIndex + 2] = g;
			this.frames[frameIndex + 3] = b;
			this.frames[frameIndex + 4] = a;
		}

		internal override float GetDuration() {
			float longest = 0;
			for (int i = 0; i < FrameCount; i++) {
				if (frames[i * 5] > longest) {
					longest = frames[i * 5];
				}
			}
			return longest;
		}
	}
}
